﻿using System;
using System.Text;
using System.Web;
using System.Web.UI;
using log4net;
using System.Collections.Specialized;
using System.Diagnostics;
using System.IO;
using System.Web.SessionState;

namespace SaturniLibrary.Web.Log
{
    public class WebLogModule : IHttpModule
    {
        //internal static ILogConfig DataProvider;
        private static readonly ILog logger = LogManager.GetLogger(typeof(WebLogModule));

        #region IHttpModule Members

        public void Init(HttpApplication context)
        {
            context.BeginRequest += ContextBeginRequest;
            context.EndRequest += ContextEndRequest;
            context.Error += ContextError;
        }

        public void Dispose()
        {
        }

        #endregion

        private void ContextBeginRequest(object sender, EventArgs e)
        {
            try
            {
                if (sender is HttpApplication)
                {
                    HttpApplication httpApplication = sender as HttpApplication;
                    HttpContext context = httpApplication.Context;

                    ThreadLogging.GetLogger().Clear();

                    ThreadLogging.GetLogger().StartStopWatch();

                    ThreadLogging.GetLogger().Log("Begin Request");

                    ThreadLogging.GetLogger().Log("Host=" + Environment.MachineName);
                    ThreadLogging.GetLogger().Log("Request Time=" + DateTime.Now);
                    ThreadLogging.GetLogger().Log("Request URL=" + context.Request.RawUrl);
                    ThreadLogging.GetLogger().Log("Request Action=" + context.Request.HttpMethod);

                    NameValueCollection headers = context.Request.Headers;
                    foreach (string header in headers)
                    {
                        ThreadLogging.GetLogger().Log("Http Header, name=" + header + ", value=" + headers[header]);
                    }
                }
            }
            catch
            {
            }
        }
        private void ContextError(object sender, EventArgs e)
        {
            try
            {
                //catch error and logging into DB
                if (sender is HttpApplication)
                {
                    ThreadLogging.GetLogger().GetStopWatch().Stop();
                    ThreadLogging.GetLogger().Log("Request Error Time=" + DateTime.Now);
                    ThreadLogging.GetLogger().Log("Page total execution time = " + ThreadLogging.GetLogger().GetStopWatch().ElapsedMs() + " ms");

                    //Considering logging session data as well
                    HttpApplication httpApplication = sender as HttpApplication;
                    HttpContext context = httpApplication.Context;
                    Exception exception = httpApplication.Server.GetLastError();
                    if (exception.InnerException != null)
                    {
                        exception = exception.InnerException;
                    }
                    WebLogHelper.LogRequestInfo(context.Request);
                    WebLogHelper.LogSession(context.Session);

                    WebLogHelper.SaveExceptionLog(exception, context);
                }
            }
            catch
            {
            }
            finally
            {
                ThreadLogging.GetLogger().Clear();
            }
        }
        private void ContextEndRequest(object sender, EventArgs e)
        {
            try
            {
                //output the log if necessary
                if (sender is HttpApplication)
                {
                    HttpApplication httpApplication = sender as HttpApplication;
                    HttpContext context = httpApplication.Context;
                    WebLogHelper.LogRequestInfo(context.Request);
                    WebLogHelper.LogSession(ThreadLogging.GetLogger().Session);

                    ThreadLogging.GetLogger().Log("End Request Time=" + DateTime.Now);
                    ThreadLogging.GetLogger().Log("End Request");

                    ThreadLogging.GetLogger().GetStopWatch().Stop();
                    ThreadLogging.GetLogger().Log("Page total execution time = " + ThreadLogging.GetLogger().GetStopWatch().ElapsedMs() + " ms");

                    if (WebLogConfig.Instance.LogEnable)
                    {
                        WebLogHelper.SaveExceptionLog(ThreadLogging.GetLogger().Exception, context);
                    }
                }
            }
            catch
            {
            }
            finally
            {
                ThreadLogging.GetLogger().Clear();
            }
        }
    }
}